#pragma once
#include "fxcc/core/graph/common/Transform.h"
#include "fxcc/core/graph/common/MaterialView.h"
#include "fxcc/core/graph/common/Maps.h"

#include "fxcc/mono/Maps.h"

using namespace fxcc::platform;
using namespace fxcc::graph::common;

struct MonoToken
{
    void* m_Inst{ 0 };

    template<typename T>
    T* Get()
    {
        return reinterpret_cast<T*>(m_Inst);
    }

    template<typename T>
    const T* GetConst() const
    {
        return reinterpret_cast<const T*>(m_Inst);
    }

};

struct GameObject
{
    std::string m_Name;
    fxcc::graph::common::Transform m_Transform;
    fxcc::graph::common::MaterialView m_MaterialView;
    fxcc::graph::common::MeshMap m_MeshMap;
    mono::MonoBehivorMap m_MonoBehivorMap;

    bool m_FirstUpdate{ true };

    void StartFunc()
    {
        m_MonoBehivorMap.Invoke("OnStart", 0, {});
    }
    void OnUpdate()
    {
        if (m_FirstUpdate)
        {
            StartFunc();
            m_FirstUpdate = false;
        }
        UpdateFunc();
    }
    void UpdateFunc()
    {
        m_MonoBehivorMap.Invoke("OnUpdate", 0, {});
    }
    void OnLoad()
    {
        m_MaterialView.OnLoad();
        m_MonoBehivorMap.OnLoad();
        m_MeshMap.OnLoad();

        mono::Args args;
        args.Push((MonoObject*)this);
        m_MonoBehivorMap.Invoke("SetGameObjectPtr", 1, args);


    }

};

struct DemoScene
{
    std::vector<GameObject> m_GameObjects;
    void OnLoad()
    {
        for (auto& obj : m_GameObjects)
        {
            obj.OnLoad();
        }
    }
    void OnUpdate()
    {
        for (auto& obj : m_GameObjects)
        {
            obj.OnUpdate();
        }

    }
};